#include "account_service.h"
#include "context.h"
#include "streamdata.h"
#include "log.h"
#include "util.h"


static bool __init__ = AccountService::Instance()->Init();

bool AccountService::Init()
{
    Ctx.msg_router.BindMsg(account_proto::ACCOUNT_CMD_GEN_LOGIN_TOKEN_RESP, std::bind(&AccountService::OnGetToken, this, std::placeholders::_1));

    return true;
}

bool AccountService::HandleGetToken(const std::string& agency, const std::uint32_t agency_id, const std::string& username, const std::string& token, 
    const std::string& currency, const std::string& hall_url, const std::string& platform, const std::int64_t balance, const std::uint32_t game, const std::string& gameinfo, std::string&& trans, Sence sence)
{
    log_debug("enter");
    StreamData stream_data;
    StreamDataWriter write(stream_data);
    write.Write<Sence>(sence);
    write.WriteString(trans);
    write.WriteInt64(CTools::GetUnixTimeMs());

    account_proto::GenLoginTokenReq get_token_req;
    get_token_req.set_agency(agency);
    get_token_req.set_username(username);
    get_token_req.set_agency_id(agency_id);
    get_token_req.set_token(token);
    get_token_req.set_currency(currency);
    get_token_req.set_hall_url(hall_url);
	get_token_req.set_platform(platform);
    get_token_req.set_balance(balance);
    get_token_req.set_game(game);
    get_token_req.set_gameinfo(gameinfo);
    get_token_req.set_trans(std::move(stream_data.Data()));

    log_debug("req:%s", get_token_req.ShortDebugString().c_str());
    Ctx.host->MtSendtoSrv(account_proto::ACCOUNT_CMD_GEN_LOGIN_TOKEN_REQ, SERVER_TYPE_ACCOUNT, &get_token_req, 0);
    return true;
}
void AccountService::OnGetToken(MsgData&& data)
{
    log_debug("enter");
    do
    {
        account_proto::GenLoginTokenResp get_token_resp;
        if (!get_token_resp.ParseFromArray(data.data.c_str(), data.data.size()))
        {
            log_error("parser account_proto::UpdateResp failed, stype:%hu,svid:%u,uuid:%d", data.svtype, data.svid, data.uuid);
            break;
        }

        StreamData stream_data(std::move(*get_token_resp.mutable_trans()));
        StreamDataReader reader(stream_data);
        Sence sence = reader.Read<Sence>();
        std::string trans = reader.ReadString();
        get_token_resp.set_trans(std::move(trans));
        std::uint64_t req_time = reader.ReadInt64();
        std::uint64_t resp_time = CTools::GetUnixTimeMs();
        std::uint64_t cost_time = resp_time-req_time;
        if (cost_time > 50000)  // 大于50ms返回需要预警
        {
            log_warning("uid:%u gen token cost %lu us", get_token_resp.uid(), cost_time);
        }
        else
        {
            log_debug("uid:%u gen token cost %lu us", get_token_resp.uid(), cost_time);
        }

        auto it = m_get_token_listen.find(sence);
        if (it == m_get_token_listen.end())
        {
            log_info("sence:%d not listen, stype:%hu,svid:%u,uuid:%d", sence, data.svtype, data.svid, data.uuid);
            break;
        }
        try
        {
            it->second(std::move(get_token_resp));
        }
        catch(const std::exception& e)
        {
            log_error("catch exception:%s, sence:%d, stype:%hu,svid:%u,uuid:%u,msg:%s", e.what(), sence, data.svtype, data.svid, data.uuid, get_token_resp.ShortDebugString().c_str());
        }
        catch(...)
        {
            log_error("catch unknown exception, sence:%d, stype:%hu,svid:%u,uuid:%u,msg:%s", sence, data.svtype, data.svid, data.uuid, get_token_resp.ShortDebugString().c_str());
        }
    } while(false);
}
























